import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons';
import { useDebounceFn } from 'ahooks';
import { Button, Select, Switch, Cascader, App, Input as AntIuput } from 'antd';
import React, { useEffect, useMemo } from 'react';
import { Draggable } from 'react-beautiful-dnd';

import DndDrag from '@/components/common/DndDrag';
import { Input } from '@/components/eai-design';
import { SvgIcon } from '@/components/icon';
import NumberInput from '@/components/inputs/NumberInput';
import FormLabel from '@/components/MyBox/FormLabel';
import JsonEditor from '@/components/Textarea/JsonEditor';
import QuestionTip from '@/components/tooltip/QuestionTip';
import { t } from '@/locales/i18n';
import { VariableItemType } from '@/types/app/type';
import {
  FlowNodeInputTypeEnum,
  FlowTimeValueTypeMap,
  FlowValueTypeMap,
  VariableInputEnum,
  WorkflowIOValueTypeEnum,
} from '@/types/workflow/constant';
import { buildTree, cascaderOptionsToText } from '@/types/workflow/utils';
import { regexText } from '@/utils/regexRules';

const { TextArea } = AntIuput;

type ListValueType = { id: string; value: string; label: string }[];

type FlowNodeInputItemType = VariableItemType & {
  list?: ListValueType;
  customInputConfig?: {
    selectValueTypeList?: WorkflowIOValueTypeEnum[];
  };
  // 添加缺失的属性以匹配 workflow/io 中的类型
  renderTypeList?: FlowNodeInputTypeEnum[];
  pattern?: string;
  isArray?: boolean;
};

const isArrayInput = [
  FlowNodeInputTypeEnum.select,
  FlowNodeInputTypeEnum.input,
  FlowNodeInputTypeEnum.numberInput,
];

function InputTypeConfig({
  data,
  setData,
  isEdit,
  onClose,
  type,
  inputType,
  selectValueTypeList,
  isToolInput,
  setIsToolInput,
  defaultValueType,
  onSubmitSuccess,
  onSubmitError,
}: {
  // Common fields
  data: FlowNodeInputItemType;
  setData: React.Dispatch<React.SetStateAction<FlowNodeInputItemType>>;
  isEdit: boolean;
  onClose: () => void;
  type: 'plugin' | 'formInput' | 'variable';
  inputType: FlowNodeInputTypeEnum | VariableInputEnum;
  selectValueTypeList?: WorkflowIOValueTypeEnum[];
  // Plugin-specific fields
  isToolInput?: boolean;
  setIsToolInput?: () => void;
  defaultValueType?: WorkflowIOValueTypeEnum;

  // Update methods
  onSubmitSuccess: (data: VariableItemType, action: 'confirm' | 'continue') => void;
  onSubmitError: (e: Object) => void;
}) {
  const defaultListValue = { label: t('None'), value: '' };
  const { message } = App.useApp();

  const [cascaderText, setCascaderText] = React.useState('');

  const updateList = (text: string) => {
    const lines = text.split('\n').map((line) => line.split(','));
    const treeData = buildTree(lines);
    // 确保生成的树数据包含所有必要字段
    const treeWithIds = treeData.map((item: any) => ({
      id: item.id || Date.now().toString(),
      value: item.value || '',
      label: item.label || '',
      children: item.children
        ? item.children.map((child: any) => ({
            id: child.id || Date.now().toString(),
            value: child.value || '',
            label: child.label || '',
            children: child.children,
          }))
        : undefined,
    })) as ListValueType;

    setData((prev) => ({
      ...prev,
      list: treeWithIds,
    }));
  };

  const { run: updateCascaderData } = useDebounceFn(
    (text: string) => {
      try {
        updateList(text);
      } catch (error) {
        console.error('Failed to parse cascader data:', error);
      }
    },
    {
      wait: 300,
    },
  );

  const listValue = useMemo(() => data.list || [], [data.list]);
  const selectEnums = listValue || [];

  const mergedSelectEnums = selectEnums.map((field, index) => ({
    ...field,
    ...listValue,
  }));

  const typeLabels = {
    name: {
      formInput: t('core.module.input_name'),
      plugin: t('core.module.Field Name'),
      variable: t('Variable_name'),
    },
    description: {
      formInput: t('core.module.input_description'),
      plugin: t('field_description'),
      variable: t('variable_description'),
    },
  };

  const appendEnums = (item: { label: string; value: string }) => {
    const newList = [...(data.list || []), { ...item, id: Date.now().toString() }];
    setData((prev) => {
      return { ...prev, list: newList };
    });
  };

  const dragEnums = (newSelectEnums: { label: string; value: string }[]) => {
    const list = newSelectEnums.map((item) => {
      return { ...item, id: Date.now().toString() };
    });
    setData((prev) => {
      return { ...prev, list };
    });
  };

  const removeEnums = (index?: number) => {
    const list = data.list || [];
    if (index !== undefined) {
      const newList = [...list.slice(0, index), ...list.slice(index + 1)];
      setData((prev) => {
        return { ...prev, list: newList };
      });
    } else {
      setData((prev) => {
        return { ...prev, list: [] };
      });
    }
  };

  const valueTypeSelectList = Object.values(
    inputType === FlowNodeInputTypeEnum.time ? FlowTimeValueTypeMap : FlowValueTypeMap,
  ).map((item) => ({
    label: item.label,
    value: item.value,
  }));

  const showDateTypeSelect = useMemo(() => {
    return type !== 'formInput' || inputType === FlowNodeInputTypeEnum.time;
  }, [inputType, type]);

  const showValueTypeSelect =
    inputType === FlowNodeInputTypeEnum.time ||
    inputType === FlowNodeInputTypeEnum.reference ||
    inputType === FlowNodeInputTypeEnum.customVariable ||
    inputType === VariableInputEnum.custom;

  const showRequired = useMemo(() => {
    const list = [
      FlowNodeInputTypeEnum.addInputParam,
      FlowNodeInputTypeEnum.customVariable,
      VariableInputEnum.custom,
    ];
    return !list.includes(inputType);
  }, [inputType]);

  const showPatternInput = useMemo(() => {
    return FlowNodeInputTypeEnum.input === inputType;
  }, [inputType]);

  const showMaxLenInput = useMemo(() => {
    const list = [FlowNodeInputTypeEnum.input];
    return list.includes(inputType as FlowNodeInputTypeEnum);
  }, [inputType]);

  const showMinMaxInput = useMemo(() => {
    const list = [FlowNodeInputTypeEnum.numberInput];
    return list.includes(inputType as FlowNodeInputTypeEnum);
  }, [inputType]);

  const showArrayInput = useMemo(() => {
    return isArrayInput.includes(inputType as FlowNodeInputTypeEnum);
  }, [inputType]);

  const showDefaultValue = useMemo(() => {
    const list = [
      FlowNodeInputTypeEnum.input,
      FlowNodeInputTypeEnum.JSONEditor,
      FlowNodeInputTypeEnum.numberInput,
      FlowNodeInputTypeEnum.switch,
      FlowNodeInputTypeEnum.select,
    ];

    return list.includes(inputType as FlowNodeInputTypeEnum);
  }, [inputType]);

  const showIsToolInput = useMemo(() => {
    const list = [
      FlowNodeInputTypeEnum.reference,
      FlowNodeInputTypeEnum.JSONEditor,
      FlowNodeInputTypeEnum.input,
      FlowNodeInputTypeEnum.numberInput,
      FlowNodeInputTypeEnum.switch,
      FlowNodeInputTypeEnum.select,
    ];
    return type === 'plugin' && list.includes(inputType as FlowNodeInputTypeEnum);
  }, [inputType, type]);

  const handleSubmit = (action: 'confirm' | 'continue') => {
    if (
      inputType === FlowNodeInputTypeEnum.input &&
      data.pattern &&
      !regexText(data.defaultValue, data.pattern)
    ) {
      message.error('默认值不符合校验规则');
      return;
    }
    const d = {
      ...data,
      valueType:
        inputType === FlowNodeInputTypeEnum.custom || inputType === FlowNodeInputTypeEnum.time
          ? data.valueType
          : defaultValueType,
    };
    onSubmitSuccess(d, action);
  };

  useEffect(() => {
    if (inputType === FlowNodeInputTypeEnum.cascader) {
      if (listValue) {
        try {
          const convertedText = cascaderOptionsToText(listValue);
          setCascaderText(convertedText.join('\n'));
          // setLocalListValue(listValue);
        } catch (error) {
          console.error('Parse cascader options error:', error);
        }
      }
    }
  }, [listValue, inputType]);
  useEffect(() => {
    setData((prev) => ({
      ...prev,
      type: inputType as VariableInputEnum,
    }));
  }, [inputType, setData]);

  return (
    <div className="flex flex-1 flex-col">
      <div className="flex flex-1 flex-col gap-4">
        <div className="flex flex-col items-center gap-2">
          <FormLabel className="w-20 self-start font-medium">
            {typeLabels.name[type] || typeLabels.name.formInput}
          </FormLabel>
          <Input
            className="text-gray-600"
            placeholder="参数名称"
            value={data.key}
            onChange={(e) => {
              setData((prev) => {
                return { ...prev, key: e.target.value };
              });
            }}
          />
        </div>
        <div className="flex flex-col items-center gap-2">
          <div className="flex gap-2 self-start">
            <FormLabel className="self-start font-medium">{t('core.module.input_label')}</FormLabel>
            <QuestionTip className="font-medium" title={t('core.module.input_label_tip')} />
          </div>
          <div className="relative flex w-full">
            <Input
              maxLength={20}
              className="flex-1 text-gray-600"
              placeholder="参数在系统中显示的名称，最大长度为20个字符"
              value={data.label}
              onChange={(e) => {
                setData((prev) => {
                  return { ...prev, label: e.target.value };
                });
              }}
            />
            <div className="pointer-events-none absolute bottom-1 right-2 text-[14px] text-[#A5A9BB]">
              {data.label?.length || 0} / {20}
            </div>
          </div>
        </div>

        <div className="flex flex-col items-start gap-2">
          <FormLabel className="self-start font-medium">
            {typeLabels.description[type] || typeLabels.description.plugin}
          </FormLabel>
          <TextArea
            className="text-gray-600"
            placeholder={t('field_description_placeholder')}
            rows={3}
            value={data.description}
            onChange={(e) => {
              setData((prev) => {
                return { ...prev, description: e.target.value };
              });
            }}
          />
        </div>

        {/* value type */}
        {showDateTypeSelect && (
          <div className="flex flex-col items-start gap-2">
            <FormLabel className="self-start font-medium">{t('core.module.Data Type')}</FormLabel>
            {showValueTypeSelect ? (
              <div className="w-full flex-1">
                <Select
                  className="w-full"
                  popupClassName="workflow-dropdown"
                  options={valueTypeSelectList.filter(
                    (item) => item.value !== WorkflowIOValueTypeEnum.arrayAny,
                  )}
                  value={data.valueType}
                  onChange={(e) => {
                    setData((prev) => {
                      return { ...prev, valueType: e };
                    });
                  }}
                />
              </div>
            ) : (
              <div className="items-center text-sm">{defaultValueType}</div>
            )}
          </div>
        )}
        {showPatternInput && (
          <div className="flex flex-col items-start gap-2">
            <FormLabel className="self-start font-medium">{t('field_pattern')}</FormLabel>
            <Input
              className="flex-1 text-gray-600"
              placeholder="字段的校验规则，支持正则表达式"
              value={data.pattern}
              onChange={(e) => {
                setData((prev) => {
                  return { ...prev, pattern: e.target.value };
                });
              }}
            />
          </div>
        )}
        {showArrayInput && (
          <div className="flex flex-col items-start gap-2">
            <FormLabel className="self-start font-medium">{t('field_is_array')}</FormLabel>
            <Switch
              checked={data.isArray}
              onChange={(e) => {
                setData((prev) => {
                  return { ...prev, isArray: e };
                });
              }}
            />
          </div>
        )}
        {showRequired && (
          <div className="flex flex-col items-start gap-2">
            <FormLabel className="self-start font-medium">{t('field_required')}</FormLabel>
            <Switch
              checked={data.required}
              onChange={(e) => {
                setData((prev) => {
                  return { ...prev, required: e };
                });
              }}
            />
          </div>
        )}
        {/* reference */}
        {showIsToolInput && (
          <div className="flex flex-col items-start gap-2">
            <FormLabel className="self-start font-medium">
              {t('field_used_as_tool_input')}
            </FormLabel>
            <Switch
              checked={isToolInput}
              onChange={(e) => {
                setIsToolInput && setIsToolInput();
              }}
            />
          </div>
        )}

        {showMaxLenInput && (
          <div className="flex flex-col items-start gap-2">
            <FormLabel className="self-start font-medium">{t('core.module.Max Length')}</FormLabel>
            <NumberInput
              size="small"
              className="bg-gray-500"
              min={0}
              placeholder={t('core.module.Max Length placeholder')}
              value={data.maxLength}
              max={50000}
              onChange={(e) => {
                // @ts-ignore
                // setValue('maxLength', e || '');
                setData((prev) => {
                  return { ...prev, maxLength: e };
                });
              }}
            />
          </div>
        )}

        {showMinMaxInput && (
          <>
            <div className="flex flex-col items-start gap-2">
              <FormLabel className="self-start font-medium">{t('core.module.Max Value')}</FormLabel>
              <NumberInput
                className="bg-gray-500"
                size="small"
                value={data.max}
                min={data.min}
                onChange={(e) => {
                  // @ts-ignore
                  // setValue('max', e || '');
                  setData((prev) => {
                    return { ...prev, max: e };
                  });
                }}
              />
            </div>
            <div className="flex flex-col items-start gap-2">
              <FormLabel className="self-start font-medium">{t('core.module.Min Value')}</FormLabel>
              <NumberInput
                className="bg-gray-500"
                size="small"
                value={data.min}
                max={data.max}
                onChange={(e) => {
                  // @ts-ignore
                  // setValue('min', e || '');
                  setData((prev) => {
                    return { ...prev, min: e };
                  });
                }}
              />
            </div>
          </>
        )}

        {showDefaultValue && (
          <div className="flex flex-col items-start gap-2">
            <FormLabel className="self-start font-medium">
              {t('core.module.Default Value')}
            </FormLabel>
            <div className="flex w-full flex-1 items-start">
              {inputType === FlowNodeInputTypeEnum.numberInput && (
                <NumberInput
                  value={data.defaultValue}
                  size="small"
                  className="relative"
                  step={1}
                  min={data.min}
                  max={data.max}
                  onChange={(e) => {
                    setData((prev) => {
                      return { ...prev, defaultValue: e };
                    });
                  }}
                />
              )}
              {inputType === FlowNodeInputTypeEnum.input && (
                <div className="relative flex w-full flex-col">
                  <Input
                    className="flex-1 text-gray-500"
                    value={data.defaultValue}
                    maxLength={data.maxLength}
                    onChange={(e) => {
                      setData((prev) => {
                        return { ...prev, defaultValue: e.target.value };
                      });
                    }}
                    showCount={!!data.maxLength}
                    isError={
                      data.defaultValue &&
                      data.pattern &&
                      !regexText(data.defaultValue, data.pattern)
                    }
                    errorMessage={
                      <div className="pointer-events-none text-[14px] text-error">字段校验失败</div>
                    }
                  />
                </div>
              )}
              {inputType === FlowNodeInputTypeEnum.JSONEditor && (
                <JsonEditor
                  className="w-full bg-gray-500"
                  resize
                  onChange={(e) => {
                    setData((prev) => {
                      return { ...prev, defaultValue: e };
                    });
                  }}
                  defaultValue={data.defaultValue}
                />
              )}
              {inputType === FlowNodeInputTypeEnum.switch && (
                <Switch
                  checked={data.defaultValue === 'true'}
                  onChange={(e) => {
                    setData((prev) => {
                      return { ...prev, defaultValue: e.toString() };
                    });
                  }}
                />
              )}
              {inputType === FlowNodeInputTypeEnum.select && (
                <Select
                  popupClassName="workflow-dropdown"
                  options={[defaultListValue, ...listValue]
                    .filter((item) => item.label !== '')
                    .map((item) => ({
                      label: item.label,
                      value: item.value,
                    }))}
                  value={
                    data.defaultValue &&
                    listValue.map((item) => item.value).includes(data.defaultValue)
                      ? data.defaultValue
                      : ''
                  }
                  onChange={(e) => {
                    setData((prev) => {
                      return { ...prev, defaultValue: e };
                    });
                  }}
                  style={{ width: '200px' }}
                />
              )}
            </div>
          </div>
        )}

        {inputType === FlowNodeInputTypeEnum.addInputParam && (
          <>
            <div className="flex flex-col items-start gap-2">
              <FormLabel className="self-start font-medium">
                {t('core.module.Input Type')}
              </FormLabel>
              <span className="text-sm">{t('only_the_reference_type_is_supported')}</span>
            </div>
            <div>
              <div className="mb-1">
                <FormLabel className="w-20 font-medium">{t('optional_value_type')}</FormLabel>
                <QuestionTip title={t('optional_value_type_tip')} />
              </div>
              <Select
                popupClassName="workflow-dropdown"
                // mode="multiple"
                style={{ width: '100%', backgroundColor: '#f5f5f5' }}
                options={valueTypeSelectList}
                value={data?.customInputConfig?.selectValueTypeList || []}
                onChange={(e) => {
                  // setFieldValue('customInputConfig.selectValueTypeList', e);
                  setData((prev) => {
                    return { ...prev, 'customInputConfig.selectValueTypeList': e };
                  });
                }}
              />
            </div>
          </>
        )}

        {inputType === FlowNodeInputTypeEnum.cascader && (
          <div className="flex flex-col gap-2">
            <div className="flex flex-col items-start gap-2">
              <FormLabel className="w-20 font-medium">选项</FormLabel>
              <TextArea
                rows={8}
                value={cascaderText}
                placeholder={`请按照以下示例输入：\n北京市,北京市,北京市\n北京市,北京市,东城区\n北京市,北京市,西城区`}
                onChange={(e) => {
                  const newText = e.target.value;
                  setCascaderText(newText);
                  // updateCascaderData(newText);
                }}
                onBlur={() => {
                  updateList(cascaderText);
                }}
              />
            </div>
            <div className="flex flex-col items-start gap-2">
              <FormLabel className="w-20 font-medium">
                {t('core.workflow.inputType.tree')}
              </FormLabel>
              <Cascader options={listValue} />
            </div>
          </div>
        )}

        {inputType === FlowNodeInputTypeEnum.select && (
          <>
            <FormLabel className="self-start font-medium">
              {t('core.module.variable.variable options')}
            </FormLabel>
            <DndDrag<{ id: string; value: string }>
              onDragEndCb={(list) => {
                const newOrder = list.map((item) => item.id);
                const newSelectEnums = newOrder
                  .map((id) => mergedSelectEnums.find((item) => item.id === id))
                  .filter(Boolean) as { id: string; value: string; label: string }[];

                dragEnums(newSelectEnums);

                // 防止最后一个元素被focus
                setTimeout(() => {
                  if (document.activeElement instanceof HTMLElement) {
                    document.activeElement.blur();
                  }
                }, 0);
              }}
              dataList={mergedSelectEnums}
              renderClone={(provided, snapshot, rubric) => {
                return (
                  <div
                    {...provided.draggableProps}
                    {...provided.dragHandleProps}
                    className="rounded-md border-2 border-gray-200 bg-gray-500 p-2 shadow-md"
                  >
                    {mergedSelectEnums[rubric.source.index].value}
                  </div>
                );
              }}
            >
              {(provided) => (
                <div
                  {...provided.droppableProps}
                  ref={provided.innerRef}
                  className="flex flex-col gap-4"
                >
                  {mergedSelectEnums.map((item, i) => (
                    <Draggable key={i} draggableId={i.toString()} index={i}>
                      {(provided, snapshot) => (
                        <div
                          ref={provided.innerRef}
                          {...provided.draggableProps}
                          style={{
                            ...provided.draggableProps.style,
                            opacity: snapshot.isDragging ? 0.8 : 1,
                          }}
                        >
                          <div
                            className={`relative flex items-center ${
                              snapshot.isDragging ? 'origin-top-left  scale-50' : ''
                            }`}
                          >
                            <div className="flex w-full items-center gap-2">
                              {selectEnums.length > 1 && (
                                <div className="flex items-center" {...provided.dragHandleProps}>
                                  <SvgIcon icon="drag" />
                                </div>
                              )}
                              <Input
                                className="text-xs text-gray-600"
                                placeholder={`${t('core.module.variable.variable options')} ${
                                  i + 1
                                }`}
                                value={data?.list && data?.list[i].label ? data?.list[i].label : ''}
                                onChange={(e) => {
                                  setData((prev) => {
                                    return {
                                      ...prev,
                                      list: data?.list?.map((item, index) => {
                                        console.log(index === i, e.target.value);

                                        if (index === i) {
                                          console.log({
                                            ...item,
                                            label: e.target.value,
                                            value: e.target.value,
                                          });

                                          return {
                                            ...item,
                                            label: e.target.value,
                                            value: e.target.value,
                                          };
                                        }
                                        return item;
                                      }),
                                    };
                                  });
                                }}
                              />
                            </div>
                            {selectEnums.length > 1 && (
                              <div className="flex">
                                <Button
                                  type="link"
                                  danger
                                  className="cursor-pointer text-gray-400 hover:text-error"
                                  icon={<MinusCircleOutlined color="" />}
                                  onClick={() => removeEnums(i)}
                                />
                              </div>
                            )}
                          </div>
                        </div>
                      )}
                    </Draggable>
                  ))}
                  <div className="h-0 w-0">{provided.placeholder}</div>
                </div>
              )}
            </DndDrag>
            <Button
              type="text"
              className="py-2 text-xs font-medium"
              icon={<PlusOutlined />}
              onClick={() => appendEnums({ label: '', value: '' })}
            >
              {t('core.module.variable add option')}
            </Button>
          </>
        )}
      </div>

      <div className="mt-4 flex justify-end gap-3">
        <Button
          className="w-20 font-medium"
          style={{ background: '#F7F8FA', borderColor: '#E5E6EB' }}
          onClick={onClose}
        >
          {t('common.Close')}
        </Button>
        {!isEdit && (
          <Button
            className="w-20 font-medium"
            onClick={() => {
              onSubmitSuccess(data, 'continue');
            }}
            // type="primary"
          >
            {t('common.Continue_Adding')}
          </Button>
        )}
        <Button
          className="w-20 font-medium"
          onClick={() => {
            handleSubmit('confirm');
          }}
          type="primary"
        >
          {t('common.Confirm')}
        </Button>
      </div>
    </div>
  );
}

export default React.memo(InputTypeConfig);
